﻿using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Runtime.Remoting.Messaging;
using System.Text;

namespace ImageLib
{
    public class ParseCompletedEventArgs : AsyncCompletedEventArgs
    {
        private ImageItemCollection _collection;
        public ImageItemCollection Collection 
        {
            get { return _collection;  }
        }

        public ParseCompletedEventArgs(ImageItemCollection collection) : base(null,false,null)
        {
            _collection = collection;            
        }
    }

    public delegate void ParseCompletedEventHandler(object o, ParseCompletedEventArgs e);

    public interface IParser
    {
        String getName();
        String getVersion();
        /**/
        void Parse(String webUrl);
        ImageItemCollection getImages();
    }

    public abstract class Parser : IParser
    {
        public ImageItemCollection imageCollection;

        abstract public void Parse(String webUrl);
        abstract public ImageItemCollection getImages();

        private delegate void ParseDelegate(String weburl);
        private bool TaskIsRunning = false;
        private readonly object _sync = new object();
        public event ParseCompletedEventHandler TaskCompleted;

        public Parser() {}

        abstract public string getName();

        abstract public string getVersion();

        public override String ToString()
        {
            return getName() + " - " + getVersion();
        }

        public String getPage(String webUrl)
        {
            String httpAnswer = String.Empty;
            HttpWebRequest request;
            try
            {
                request = (HttpWebRequest)WebRequest.Create(webUrl);
                byte[] buf = new byte[16384];
                StringBuilder responseBody = new StringBuilder();
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream resStream = response.GetResponseStream();
                string tempString = null;
                int count = 0;
                do
                {
                    count = resStream.Read(buf, 0, buf.Length);
                    if (count != 0)
                    {
                        tempString = Encoding.UTF8.GetString(buf, 0, count);
                        responseBody.Append(tempString);
                    }
                } while (count > 0);
                httpAnswer = responseBody.ToString();
                /*
                Console.WriteLine("**********************************************************************");
                Console.WriteLine(httpAnswer);
                Console.WriteLine("**********************************************************************");
                 * */
            }
            catch (Exception ex) { }
            return httpAnswer;
        }

        public void ParseAsync(String webUrl)
        {
            ParseDelegate worker = new ParseDelegate(Parse);
            AsyncCallback completedCallback = new AsyncCallback(TaskCompletedCallback);

            lock (_sync)
            {
                if (TaskIsRunning)
                    throw new InvalidOperationException("The control is currently busy.");
                AsyncOperation async = AsyncOperationManager.CreateOperation(null);
                worker.BeginInvoke(webUrl, completedCallback, async);
                TaskIsRunning = true;
            }
        }

        private void TaskCompletedCallback(IAsyncResult ar)
        {
            // get the original worker delegate and the AsyncOperation instance
            ParseDelegate worker = (ParseDelegate)((AsyncResult)ar).AsyncDelegate;
            AsyncOperation async = (AsyncOperation)ar.AsyncState;

            // finish the asynchronous operation
            worker.EndInvoke(ar);

            // clear the running task flag
            lock (_sync)
            {
                TaskIsRunning = false;
            }

            // raise the completed event
            ParseCompletedEventArgs completedArgs = new ParseCompletedEventArgs(imageCollection);
            async.PostOperationCompleted(
                    delegate(object e)
                    {
                        OnTaskCompleted((ParseCompletedEventArgs)e);
                    },
                    completedArgs
            );
        }

        protected virtual void OnTaskCompleted(ParseCompletedEventArgs e)
        {
            if (TaskCompleted != null)
                TaskCompleted(this, e);
        }

        public bool IsBusy
        {
            get { return TaskIsRunning; }
        }
    }
}
